package com.rfsp.common.jwt;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.rfsp.common.base.ResultVO;
import com.rfsp.common.feign.OrgFeign;
import com.rfsp.common.feign.PermFeign;
import com.rfsp.common.feign.UserFeign;
import com.rfsp.common.pojo.vo.OrgVO;
import com.rfsp.common.pojo.vo.PermVO;
import com.rfsp.common.pojo.vo.UserVO;
import com.rfsp.common.service.PriviService;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class JwtRealm extends AuthorizingRealm {
	
	public Logger log = LoggerFactory.getLogger(JwtRealm.class);

    @Autowired
    private OrgFeign orgFeign;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    PermFeign permFeign;
    
    @Autowired
    PriviService permService;

    /**
     * 必须重写此方法，不然Shiro会报错
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }


    /**
     * 认证
     * 默认使用此方法进行用户名正确与否验证，错误抛出异常即可。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
        String token = (String) authToken.getCredentials();

        SimpleAuthenticationInfo authc = new SimpleAuthenticationInfo(token, token, JwtRealm.class.getName());
        return authc;
    }

    /**
     * 鉴权
     * 只有当需要检测用户权限的时候才会调用此方法，例如checkRole,checkPermission之类的
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String token=principals.toString();
        Long userId = JwtUtil.getUserId(token);
        Long orgId = JwtUtil.getOrgId(token);

        ResultVO<UserVO> ur = userFeign.get("", userId);
        ResultVO<OrgVO> or  = orgFeign.get(orgId);

        List<String> roleCodeList = permService.queryRoleCodeList(ur.getData(), or.getData());

        //不验证登录
        CompletableFuture<ResultVO<List<PermVO>>> listFuture1 = CompletableFuture.supplyAsync(() -> permFeign.listByNotValidateLogin(""));

        //不验证角色
        CompletableFuture<ResultVO<List<PermVO>>> listFuture2 = CompletableFuture.supplyAsync(() -> permFeign.listByNotValidateRole(""));

        //角色权限
        PermVO sdto = new PermVO();
//        sdto.setRoleCodeList(roleCodeList);

        CompletableFuture<ResultVO<List<PermVO>>> listFuture3 = CompletableFuture.supplyAsync(() -> permFeign.list("aaa", sdto));
        
        CompletableFuture.allOf(listFuture1,listFuture3,listFuture3);


        SimpleAuthorizationInfo authz = new SimpleAuthorizationInfo();

        //允许的角色
        for(String roleCode:roleCodeList){
            authz.addRole(roleCode);
        }

        //允许的权限
        try {
            List<PermVO> voList=new ArrayList<PermVO>();
            voList.addAll(listFuture1.get().getData());
            voList.addAll(listFuture2.get().getData());
            voList.addAll(listFuture3.get().getData());

            for(PermVO vo : voList){
                authz.addStringPermission(vo.getCode());
                //authz.addStringPermission(vo.getDataUrl());
                //authz.addStringPermission(vo.getRuleUrl());
            }
        } catch (InterruptedException e) {
        	log.error(e.getMessage());
        } catch (ExecutionException e) {
        	log.error(e.getMessage());
        }finally {
        }

        /*
        for(RoleVO role : permFeign.listRoles(userId)){
            authz.addRole(role.getRoleCode());
            for(PermissionVO p : permFeign.listPermissions(role.getId())){
                authz.addStringPermission(p.getPermissionCode());
                authz.addStringPermission(p.getUrl());
            }
        }
        */

        return authz;
    }

}
